using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.IO;

using ClassBuilderWizard.Interfaces;

namespace ClassBuilderWizard.DefaultPlugins.Forms
{
    public partial class frmManualWizardStep1 : WizardFormBase
    {
        private AutoCompleteStringCollection _Types;
        private ProjectType _Language;

        public frmManualWizardStep1(ProjectType language)
        {
            InitializeComponent();

            this._Language = language;
            this._Types = GetPrimitiveTypeList();
        }

        public List<ManualProperty> GetProperties()
        {
            List<ManualProperty> props = new List<ManualProperty>();

            foreach (ListViewItem lvi in lvFieldList.Items)
            {
                ManualProperty mp = new ManualProperty();
                mp.Name = lvi.SubItems[0].Text;
                Type t = Type.GetType(lvi.SubItems[1].Text, false);
                if (t == null)
                    t = Type.GetType(string.Format("System.{0}", lvi.SubItems[1].Text), false);
                mp.CLRType = t;

                props.Add(mp);
            }

            return props;
        }

        private AutoCompleteStringCollection GetPrimitiveTypeList()
        {
            AutoCompleteStringCollection types = new AutoCompleteStringCollection();
            //get the proper names for the types in the System namespace
            foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (Path.GetFileName(asm.Location) == "mscorlib.dll")
                {
                    foreach (Type t in asm.GetTypes())
                    {
                        if (!t.IsAbstract)
                            types.Add(t.Name);
                    }
                    break; //don't need to iterate through the rest of the assemblies
                }
            }

            return types;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (txtField.Text.Trim() != string.Empty && txtType.Text.Trim() != string.Empty)
            {
                ListViewItem lvi = new ListViewItem(new string[] { txtField.Text.Trim(), txtType.Text.Trim() });
                lvFieldList.Items.Add(lvi);

                txtField.Text = "";
                txtType.Text = "";

                this.btnFinish.Enabled = true;

                txtType.Focus();
            }
            else
            {
                MessageBox.Show("Please enter a field name and a C# data type");
            }
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvFieldList.SelectedItems)
            {
                lvFieldList.Items.Remove(lvi);
            }

            if (lvFieldList.Items.Count <= 0) this.btnFinish.Enabled = false;
        }

        private void btnUp_Click(object sender, EventArgs e)
        {
            MoveListViewItem(true);
        }

        private void btnDown_Click(object sender, EventArgs e)
        {
            MoveListViewItem(false);
        }

        private void MoveListViewItem(bool moveUp)
        {
            //move the selected items up
            if (lvFieldList.SelectedItems.Count > 0)
            {
                foreach (ListViewItem lvi in lvFieldList.SelectedItems)
                {
                    int oldIndex = lvi.Index;
                    int newIndex;
                    if (moveUp)
                        newIndex = lvi.Index - 1;
                    else
                        newIndex = lvi.Index + 1;

                    //ignore a move up request for the first item and ignore move down request for the last item
                    if (!(oldIndex == 0 && moveUp) && !(oldIndex >= (lvFieldList.Items.Count - 1) && !moveUp))
                    {
                        //cache the item next to the moving item
                        ListViewItem cache = (ListViewItem)lvFieldList.Items[newIndex].Clone();
                        //replace the item next to the moving item with the moving item
                        lvFieldList.Items[newIndex] = (ListViewItem)lvi.Clone();
                        //replace the moving item with the item next to it
                        lvFieldList.Items[oldIndex] = (ListViewItem)cache.Clone();

                        //select the moved item
                        lvFieldList.Items[newIndex].Selected = true;
                        lvFieldList.Refresh();
                    }
                    lvFieldList.Focus();
                }
            }
        }

        private void frmManualWizardStep1_Load(object sender, EventArgs e)
        {
            Bind_Types();
        }

        private void Bind_Types()
        {
            txtType.AutoCompleteCustomSource = this._Types;
        }
    }
}